//
//  TestSerializationFinal.swift
//

import XCTest
import ChronoxorProto
import ChronoxorTest

class TestSerializationFinal: XCTestCase {
    func testSerializationDomain() {
        // Create a new account with some orders
        var account1 = Account(id: 1, name: "Test", state: State.good, wallet: Balance(currency: "USD", amount: 1000.0), asset: Balance(currency: "EUR", amount: 100.0), orders: [])
        account1.orders.append(Order(id: 1, symbol: "EURUSD", side: OrderSide.buy, type: OrderType.market, price: 1.23456, volume: 1000.0))
        account1.orders.append(Order(id: 2, symbol: "EURUSD", side: OrderSide.sell, type: OrderType.limit, price: 1.0, volume: 100.0))
        account1.orders.append(Order(id: 3, symbol: "EURUSD", side: OrderSide.buy, type: OrderType.stop, price: 1.5, volume: 10.0))

        // Serialize the account to the FBE stream
        let writer = AccountFinalModel()
        let serialized = try! writer.serialize(value: account1)
        XCTAssertEqual(serialized, writer.buffer.size)
        XCTAssertTrue(writer.verify())
        writer.next(prev: serialized)

        // Check the serialized FBE size
        XCTAssertEqual(writer.buffer.size, 152)

        // Deserialize the account from the FBE stream
        var account2 = Account()
        let reader = AccountFinalModel()
        reader.attach(buffer: writer.buffer)
        XCTAssertTrue(reader.verify())
        let deserialized = reader.deserialize(value: &account2)
        XCTAssertEqual(deserialized, reader.buffer.size)
        reader.next(prev: deserialized)

        XCTAssertEqual(account2.id, 1)
        XCTAssertEqual(account2.name, "Test")
        XCTAssertTrue(account2.state.hasFlags(flags: State.good))
        XCTAssertEqual(account2.wallet.currency, "USD")
        XCTAssertEqual(account2.wallet.amount, 1000.0)
        XCTAssertNotEqual(account2.asset, nil)
        XCTAssertEqual(account2.asset!.currency, "EUR")
        XCTAssertEqual(account2.asset!.amount, 100.0)
        XCTAssertEqual(account2.orders.count, 3)
        XCTAssertEqual(account2.orders[0].id, 1)
        XCTAssertEqual(account2.orders[0].symbol, "EURUSD")
        XCTAssertEqual(account2.orders[0].side, OrderSide.buy)
        XCTAssertEqual(account2.orders[0].type, OrderType.market)
        XCTAssertEqual(account2.orders[0].price, 1.23456)
        XCTAssertEqual(account2.orders[0].volume, 1000.0)
        XCTAssertEqual(account2.orders[1].id, 2)
        XCTAssertEqual(account2.orders[1].symbol, "EURUSD")
        XCTAssertEqual(account2.orders[1].side, OrderSide.sell)
        XCTAssertEqual(account2.orders[1].type, OrderType.limit)
        XCTAssertEqual(account2.orders[1].price, 1.0)
        XCTAssertEqual(account2.orders[1].volume, 100.0)
        XCTAssertEqual(account2.orders[2].id, 3)
        XCTAssertEqual(account2.orders[2].symbol, "EURUSD")
        XCTAssertEqual(account2.orders[2].side, OrderSide.buy)
        XCTAssertEqual(account2.orders[2].type, OrderType.stop)
        XCTAssertEqual(account2.orders[2].price, 1.5)
        XCTAssertEqual(account2.orders[2].volume, 10.0)
    }

    func testSerializationStructSimple() {
        // Create a new struct
        let struct1 = StructSimple()

        // Serialize the struct to the FBE stream
        let writer = StructSimpleFinalModel()
        XCTAssertEqual(writer.fbeType, 110)
        let serialized = try! writer.serialize(value: struct1)
        XCTAssertEqual(serialized, writer.buffer.size)
        XCTAssertTrue(writer.verify())
        writer.next(prev: serialized)

        // Check the serialized FBE size
        XCTAssertEqual(writer.buffer.size, 304)

        // Deserialize the struct from the FBE stream
        var struct2 = StructSimple()
        let reader = StructSimpleFinalModel()
        XCTAssertEqual(reader.fbeType, 110)

        reader.attach(buffer: writer.buffer)
        XCTAssertTrue(reader.verify())
        let deserialized = reader.deserialize(value: &struct2)
        XCTAssertEqual(deserialized, reader.buffer.size)
        reader.next(prev: deserialized)

        XCTAssertEqual(struct2.f1, false)
        XCTAssertEqual(struct2.f2, true)
        XCTAssertEqual(struct2.f3, 0)
        XCTAssertEqual(struct2.f4, 0xFF)
        XCTAssertEqual(struct2.f5, "\0")
        XCTAssertEqual(struct2.f6, "!")
        XCTAssertEqual(struct2.f7, Character(UnicodeScalar(0)!))
        XCTAssertEqual(struct2.f8, Character(UnicodeScalar(0x0444)!))
        XCTAssertEqual(struct2.f9, 0)
        XCTAssertEqual(struct2.f10, 127)
        XCTAssertEqual(struct2.f11, 0)
        XCTAssertEqual(struct2.f12, 0xFF)
        XCTAssertEqual(struct2.f13, 0)
        XCTAssertEqual(struct2.f14, 32767)
        XCTAssertEqual(struct2.f15, 0)
        XCTAssertEqual(struct2.f16, 0xFFFF)
        XCTAssertEqual(struct2.f17, 0)
        XCTAssertEqual(struct2.f18, 2147483647)
        XCTAssertEqual(struct2.f19, 0)
        XCTAssertEqual(struct2.f20, 0xFFFFFFFF)
        XCTAssertEqual(struct2.f21, 0)
        XCTAssertEqual(struct2.f22, 9223372036854775807)
        XCTAssertEqual(struct2.f23, 0)
        XCTAssertEqual(struct2.f24, 0xFFFFFFFFFFFFFFFF)
        XCTAssertEqual(struct2.f25, 0.0)
        XCTAssertTrue(abs(struct2.f26 - 123.456) < 0.0001)
        XCTAssertEqual(struct2.f27, 0.0)
        XCTAssertTrue(abs(struct2.f28 - -123.567e+123) < 1e+123)
        XCTAssertEqual(struct2.f29, Decimal.zero)
        XCTAssertEqual(struct2.f30, Decimal(string: "123456.123456") ?? .nan)
        XCTAssertEqual(struct2.f31, "")
        XCTAssertEqual(struct2.f32, "Initial string!")
        XCTAssertTrue(struct2.f33 == Date(timeIntervalSince1970: 0))
        XCTAssertTrue(struct2.f34 == Date(timeIntervalSince1970: 0))
        XCTAssertTrue(struct2.f35 > Date(timeIntervalSince1970: 1514764800)) // 01/01/2018
        XCTAssertTrue(struct2.f36 == UUID(uuidString: "00000000-0000-0000-0000-000000000000"))
        XCTAssertTrue(struct2.f37 != UUID(uuidString: "123e4567-e89b-12d3-a456-426655440000"))
        XCTAssertTrue(struct2.f38 == UUID(uuidString: "123e4567-e89b-12d3-a456-426655440000"))

        XCTAssertEqual(struct2.f1, struct1.f1)
        XCTAssertEqual(struct2.f2, struct1.f2)
        XCTAssertEqual(struct2.f3, struct1.f3)
        XCTAssertEqual(struct2.f4, struct1.f4)
        XCTAssertEqual(struct2.f5, struct1.f5)
        XCTAssertEqual(struct2.f6, struct1.f6)
        XCTAssertEqual(struct2.f7, struct1.f7)
        XCTAssertEqual(struct2.f8, struct1.f8)
        XCTAssertEqual(struct2.f9, struct1.f9)
        XCTAssertEqual(struct2.f10, struct1.f10)
        XCTAssertEqual(struct2.f11, struct1.f11)
        XCTAssertEqual(struct2.f12, struct1.f12)
        XCTAssertEqual(struct2.f13, struct1.f13)
        XCTAssertEqual(struct2.f14, struct1.f14)
        XCTAssertEqual(struct2.f15, struct1.f15)
        XCTAssertEqual(struct2.f16, struct1.f16)
        XCTAssertEqual(struct2.f17, struct1.f17)
        XCTAssertEqual(struct2.f18, struct1.f18)
        XCTAssertEqual(struct2.f19, struct1.f19)
        XCTAssertEqual(struct2.f20, struct1.f20)
        XCTAssertEqual(struct2.f21, struct1.f21)
        XCTAssertEqual(struct2.f22, struct1.f22)
        XCTAssertEqual(struct2.f23, struct1.f23)
        XCTAssertEqual(struct2.f24, struct1.f24)
        XCTAssertEqual(struct2.f25, struct1.f25)
        XCTAssertEqual(struct2.f26, struct1.f26)
        XCTAssertEqual(struct2.f27, struct1.f27)
        XCTAssertEqual(struct2.f28, struct1.f28)
        XCTAssertEqual(struct2.f29, struct1.f29)
        XCTAssertEqual(struct2.f30, struct1.f30)
        XCTAssertEqual(struct2.f31, struct1.f31)
        XCTAssertEqual(struct2.f32, struct1.f32)
        XCTAssertEqual(struct2.f33, struct1.f33)
        XCTAssertEqual(struct2.f34, struct1.f34)
        XCTAssertEqual(floor(struct2.f35.timeIntervalSince1970 * 1000), floor(struct1.f35.timeIntervalSince1970 * 1000))
        XCTAssertEqual(struct2.f36, struct1.f36)
        XCTAssertEqual(struct2.f37, struct1.f37)
        XCTAssertEqual(struct2.f38, struct1.f38)
        XCTAssertEqual(struct2.f39, struct1.f39)
        XCTAssertEqual(struct2.f40, struct1.f40)
    }

    func testSerializationStructOptional() {
        // Create a new struct
        let struct1 = ChronoxorTest.StructOptional()

        // Serialize the struct to the FBE stream
        let writer = StructOptionalFinalModel()
        XCTAssertEqual(writer.fbeType, 111)

        let serialized = try! writer.serialize(value: struct1)
        XCTAssertEqual(serialized, writer.buffer.size)
        XCTAssertTrue(writer.verify())
        writer.next(prev: serialized)

        // Check the serialized FBE size
        XCTAssertEqual(writer.buffer.size, 478)

        // Deserialize the struct from the FBE stream
        var struct2 = StructOptional()
        let reader = StructOptionalFinalModel()
        XCTAssertEqual(reader.fbeType, 111)

        reader.attach(buffer: writer.buffer)
        XCTAssertTrue(reader.verify())
        let deserialized = reader.deserialize(value: &struct2)
        XCTAssertEqual(deserialized, reader.buffer.size)
        reader.next(prev: deserialized)

        XCTAssertEqual(struct2.f1, false)
        XCTAssertEqual(struct2.f2, true)
        XCTAssertEqual(struct2.f3, 0)
        XCTAssertEqual(struct2.f4, 0xFF)
        XCTAssertEqual(struct2.f5, "\0")
        XCTAssertEqual(struct2.f6, "!")
        XCTAssertEqual(struct2.f7, Character(UnicodeScalar(0)!))
        XCTAssertEqual(struct2.f8, Character(UnicodeScalar(0x0444)!))
        XCTAssertEqual(struct2.f9, 0)
        XCTAssertEqual(struct2.f10, 127)
        XCTAssertEqual(struct2.f11, 0)
        XCTAssertEqual(struct2.f12, 0xFF)
        XCTAssertEqual(struct2.f13, 0)
        XCTAssertEqual(struct2.f14, 32767)
        XCTAssertEqual(struct2.f15, 0)
        XCTAssertEqual(struct2.f16, 0xFFFF)
        XCTAssertEqual(struct2.f17, 0)
        XCTAssertEqual(struct2.f18, 2147483647)
        XCTAssertEqual(struct2.f19, 0)
        XCTAssertEqual(struct2.f20, 0xFFFFFFFF)
        XCTAssertEqual(struct2.f21, 0)
        XCTAssertEqual(struct2.f22, 9223372036854775807)
        XCTAssertEqual(struct2.f23, 0)
        XCTAssertEqual(struct2.f24, 0xFFFFFFFFFFFFFFFF)
        XCTAssertEqual(struct2.f25, 0.0)
        XCTAssertTrue(abs(struct2.f26 - 123.456) < 0.0001)
        XCTAssertEqual(struct2.f27, 0.0)
        XCTAssertTrue(abs(struct2.f28 - -123.567e+123) < 1e+123)
        XCTAssertEqual(struct2.f29, Decimal(0))
        XCTAssertEqual(struct2.f30, Decimal(string: "123456.123456") ?? .nan)
        XCTAssertEqual(struct2.f31, "")
        XCTAssertEqual(struct2.f32, "Initial string!")
        XCTAssertTrue(struct2.f33 == Date(timeIntervalSince1970: 0))
        XCTAssertTrue(struct2.f34 == Date(timeIntervalSince1970: 0))
        XCTAssertTrue(struct2.f35 > Date(timeIntervalSince1970: 1514764800)) // 01/01/2018
        XCTAssertTrue(struct2.f36 == UUID(uuidString: "00000000-0000-0000-0000-000000000000"))
        XCTAssertTrue(struct2.f37 != UUID(uuidString: "00000000-0000-0000-0000-000000000000"))
        XCTAssertTrue(struct2.f38 == UUID(uuidString: "123e4567-e89b-12d3-a456-426655440000"))

        XCTAssertEqual(struct2.f100, nil)
        XCTAssertEqual(struct2.f101!, true)
        XCTAssertEqual(struct2.f102, nil)
        XCTAssertEqual(struct2.f103, nil)
        XCTAssertNotEqual(struct2.f104, nil)
        XCTAssertEqual(struct2.f104!, 0xFF)
        XCTAssertEqual(struct2.f105, nil)
        XCTAssertEqual(struct2.f106, nil)
        XCTAssertNotEqual(struct2.f107, nil)
        XCTAssertEqual(struct2.f107!, "!")
        XCTAssertEqual(struct2.f108, nil)
        XCTAssertEqual(struct2.f109, nil)
        XCTAssertNotEqual(struct2.f110, nil)
        XCTAssertEqual(struct2.f110!, Character(UnicodeScalar(0x0444)!))
        XCTAssertEqual(struct2.f111, nil)
        XCTAssertEqual(struct2.f112, nil)
        XCTAssertNotEqual(struct2.f113, nil)
        XCTAssertEqual(struct2.f113!, 127)
        XCTAssertEqual(struct2.f114, nil)
        XCTAssertEqual(struct2.f115, nil)
        XCTAssertNotEqual(struct2.f116, nil)
        XCTAssertEqual(struct2.f116!, 0xFF)
        XCTAssertEqual(struct2.f117, nil)
        XCTAssertEqual(struct2.f118, nil)
        XCTAssertNotEqual(struct2.f119, nil)
        XCTAssertEqual(struct2.f119!, 32767)
        XCTAssertEqual(struct2.f120, nil)
        XCTAssertEqual(struct2.f121, nil)
        XCTAssertNotEqual(struct2.f122, nil)
        XCTAssertEqual(struct2.f122!, 0xFFFF)
        XCTAssertEqual(struct2.f123, nil)
        XCTAssertEqual(struct2.f124, nil)
        XCTAssertNotEqual(struct2.f125, nil)
        XCTAssertEqual(struct2.f125!, 2147483647)
        XCTAssertEqual(struct2.f126, nil)
        XCTAssertEqual(struct2.f127, nil)
        XCTAssertNotEqual(struct2.f128, nil)
        XCTAssertEqual(struct2.f128!, 0xFFFFFFFF)
        XCTAssertEqual(struct2.f129, nil)
        XCTAssertEqual(struct2.f130, nil)
        XCTAssertNotEqual(struct2.f131, nil)
        XCTAssertEqual(struct2.f131!, 9223372036854775807)
        XCTAssertEqual(struct2.f132, nil)
        XCTAssertEqual(struct2.f133, nil)
        XCTAssertNotEqual(struct2.f131, nil)
        XCTAssertEqual(struct2.f134!, 0xFFFFFFFFFFFFFFFF)
        XCTAssertEqual(struct2.f135, nil)
        XCTAssertEqual(struct2.f136, nil)
        XCTAssertNotEqual(struct2.f137, nil)
        XCTAssertTrue(abs(struct2.f137! - 123.456) < 0.0001)
        XCTAssertEqual(struct2.f138, nil)
        XCTAssertEqual(struct2.f139, nil)
        XCTAssertNotEqual(struct2.f140, nil)
        XCTAssertTrue(abs(struct2.f140! - -123.567e+123) < 1e+123)
        XCTAssertEqual(struct2.f141, nil)
        XCTAssertEqual(struct2.f142, nil)
        XCTAssertNotEqual(struct2.f143, nil)
        XCTAssertEqual(struct2.f143, Decimal(string: "123456.123456") ?? .nan)
        XCTAssertEqual(struct2.f144, nil)
        XCTAssertEqual(struct2.f145, nil)
        XCTAssertNotEqual(struct2.f146, nil)
        XCTAssertEqual(struct2.f146, "Initial string!")
        XCTAssertEqual(struct2.f147, nil)
        XCTAssertEqual(struct2.f148, nil)
        XCTAssertNotEqual(struct2.f149, nil)
        XCTAssertTrue(struct2.f149! > Date(timeIntervalSince1970: 1514764800)) // 01/01/2018
        XCTAssertEqual(struct2.f150, nil)
        XCTAssertEqual(struct2.f151, nil)
        XCTAssertNotEqual(struct2.f152, nil)
        XCTAssertTrue(struct2.f152! == UUID(uuidString: "123e4567-e89b-12d3-a456-426655440000"))
        XCTAssertEqual(struct2.f153, nil)
        XCTAssertEqual(struct2.f154, nil)
        XCTAssertEqual(struct2.f155, nil)
        XCTAssertEqual(struct2.f156, nil)
        XCTAssertEqual(struct2.f157, nil)
        XCTAssertEqual(struct2.f158, nil)
        XCTAssertEqual(struct2.f159, nil)
        XCTAssertEqual(struct2.f160, nil)
        XCTAssertEqual(struct2.f161, nil)
        XCTAssertEqual(struct2.f162, nil)
        XCTAssertEqual(struct2.f163, nil)
        XCTAssertEqual(struct2.f164, nil)
        XCTAssertEqual(struct2.f165, nil)

        XCTAssertEqual(struct2.f1, struct1.f1)
        XCTAssertEqual(struct2.f2, struct1.f2)
        XCTAssertEqual(struct2.f3, struct1.f3)
        XCTAssertEqual(struct2.f4, struct1.f4)
        XCTAssertEqual(struct2.f5, struct1.f5)
        XCTAssertEqual(struct2.f6, struct1.f6)
        XCTAssertEqual(struct2.f7, struct1.f7)
        XCTAssertEqual(struct2.f8, struct1.f8)
        XCTAssertEqual(struct2.f9, struct1.f9)
        XCTAssertEqual(struct2.f10, struct1.f10)
        XCTAssertEqual(struct2.f11, struct1.f11)
        XCTAssertEqual(struct2.f12, struct1.f12)
        XCTAssertEqual(struct2.f13, struct1.f13)
        XCTAssertEqual(struct2.f14, struct1.f14)
        XCTAssertEqual(struct2.f15, struct1.f15)
        XCTAssertEqual(struct2.f16, struct1.f16)
        XCTAssertEqual(struct2.f17, struct1.f17)
        XCTAssertEqual(struct2.f18, struct1.f18)
        XCTAssertEqual(struct2.f19, struct1.f19)
        XCTAssertEqual(struct2.f20, struct1.f20)
        XCTAssertEqual(struct2.f21, struct1.f21)
        XCTAssertEqual(struct2.f22, struct1.f22)
        XCTAssertEqual(struct2.f23, struct1.f23)
        XCTAssertEqual(struct2.f24, struct1.f24)
        XCTAssertEqual(struct2.f25, struct1.f25)
        XCTAssertEqual(struct2.f26, struct1.f26)
        XCTAssertEqual(struct2.f27, struct1.f27)
        XCTAssertEqual(struct2.f28, struct1.f28)
        XCTAssertEqual(struct2.f29, struct1.f29)
        XCTAssertEqual(struct2.f30, struct1.f30)
        XCTAssertEqual(struct2.f31, struct1.f31)
        XCTAssertEqual(struct2.f32, struct1.f32)
        XCTAssertEqual(struct2.f33, struct1.f33)
        XCTAssertEqual(struct2.f34, struct1.f34)
        XCTAssertEqual(floor(struct2.f35.timeIntervalSince1970 * 1000), floor(struct1.f35.timeIntervalSince1970 * 1000))
        XCTAssertEqual(struct2.f36, struct1.f36)
        XCTAssertEqual(struct2.f37, struct1.f37)
        XCTAssertEqual(struct2.f38, struct1.f38)
        XCTAssertEqual(struct2.f39, struct1.f39)
        XCTAssertEqual(struct2.f40, struct1.f40)

        XCTAssertEqual(struct2.f100, struct1.f100)
        XCTAssertEqual(struct2.f101, struct1.f101)
        XCTAssertEqual(struct2.f102, struct1.f102)
        XCTAssertEqual(struct2.f103, struct1.f103)
        XCTAssertEqual(struct2.f104, struct1.f104)
        XCTAssertEqual(struct2.f105, struct1.f105)
        XCTAssertEqual(struct2.f106, struct1.f106)
        XCTAssertEqual(struct2.f107, struct1.f107)
        XCTAssertEqual(struct2.f108, struct1.f108)
        XCTAssertEqual(struct2.f109, struct1.f109)
        XCTAssertEqual(struct2.f110, struct1.f110)
        XCTAssertEqual(struct2.f111, struct1.f111)
        XCTAssertEqual(struct2.f112, struct1.f112)
        XCTAssertEqual(struct2.f113, struct1.f113)
        XCTAssertEqual(struct2.f114, struct1.f114)
        XCTAssertEqual(struct2.f115, struct1.f115)
        XCTAssertEqual(struct2.f116, struct1.f116)
        XCTAssertEqual(struct2.f117, struct1.f117)
        XCTAssertEqual(struct2.f118, struct1.f118)
        XCTAssertEqual(struct2.f119, struct1.f119)
        XCTAssertEqual(struct2.f120, struct1.f120)
        XCTAssertEqual(struct2.f121, struct1.f121)
        XCTAssertEqual(struct2.f122, struct1.f122)
        XCTAssertEqual(struct2.f123, struct1.f123)
        XCTAssertEqual(struct2.f124, struct1.f124)
        XCTAssertEqual(struct2.f125, struct1.f125)
        XCTAssertEqual(struct2.f126, struct1.f126)
        XCTAssertEqual(struct2.f127, struct1.f127)
        XCTAssertEqual(struct2.f128, struct1.f128)
        XCTAssertEqual(struct2.f129, struct1.f129)
        XCTAssertEqual(struct2.f130, struct1.f130)
        XCTAssertEqual(struct2.f131, struct1.f131)
        XCTAssertEqual(struct2.f132, struct1.f132)
        XCTAssertEqual(struct2.f133, struct1.f133)
        XCTAssertEqual(struct2.f134, struct1.f134)
        XCTAssertEqual(struct2.f135, struct1.f135)
        XCTAssertEqual(struct2.f136, struct1.f136)
        XCTAssertEqual(struct2.f137, struct1.f137)
        XCTAssertEqual(struct2.f138, struct1.f138)
        XCTAssertEqual(struct2.f139, struct1.f139)
        XCTAssertEqual(struct2.f140, struct1.f140)
        XCTAssertEqual(struct2.f141, struct1.f141)
        XCTAssertEqual(struct2.f142, struct1.f142)
        XCTAssertEqual(struct2.f143, struct1.f143)
        XCTAssertEqual(struct2.f144, struct1.f144)
        XCTAssertEqual(struct2.f145, struct1.f145)
        XCTAssertEqual(struct2.f146, struct1.f146)
        XCTAssertEqual(struct2.f147, struct1.f147)
        XCTAssertEqual(struct2.f148, struct1.f148)
        XCTAssertEqual(floor(struct2.f149!.timeIntervalSince1970 * 1000), floor(struct1.f149!.timeIntervalSince1970 * 1000))
        XCTAssertEqual(struct2.f150, struct1.f150)
        XCTAssertEqual(struct2.f151, struct1.f151)
        XCTAssertEqual(struct2.f152, struct1.f152)
        XCTAssertEqual(struct2.f153, struct1.f153)
        XCTAssertEqual(struct2.f154, struct1.f154)
        XCTAssertEqual(struct2.f155, struct1.f155)
        XCTAssertEqual(struct2.f156, struct1.f156)
        XCTAssertEqual(struct2.f157, struct1.f157)
    }

    func testSerializationStructNested() {
        // Create a new struct
        let struct1 = StructNested()

        // Serialize the struct to the FBE stream
        let writer = StructNestedFinalModel()
        XCTAssertEqual(writer.fbeType, 112)

        let serialized = try! writer.serialize(value: struct1)
        XCTAssertEqual(serialized, writer.buffer.size)
        XCTAssertTrue(writer.verify())
        writer.next(prev: serialized)

        // Check the serialized FBE size
        XCTAssertEqual(writer.buffer.size, 1267)

        // Deserialize the struct from the FBE stream
        var struct2 = StructNested()
        let reader = StructNestedFinalModel()
        XCTAssertEqual(reader.fbeType, 112)

        reader.attach(buffer: writer.buffer)
        XCTAssertTrue(reader.verify())
        let deserialized = reader.deserialize(value: &struct2)
        XCTAssertEqual(deserialized, reader.buffer.size)
        reader.next(prev: deserialized)

        XCTAssertEqual(struct2.f1, false)
        XCTAssertEqual(struct2.f2, true)
        XCTAssertEqual(struct2.f3, 0)
        XCTAssertEqual(struct2.f4, 0xFF)
        XCTAssertEqual(struct2.f5, "\0")
        XCTAssertEqual(struct2.f6, "!")
        XCTAssertEqual(struct2.f7, Character(UnicodeScalar(0)!))
        XCTAssertEqual(struct2.f8, Character(UnicodeScalar(0x0444)!))
        XCTAssertEqual(struct2.f9, 0)
        XCTAssertEqual(struct2.f10, 127)
        XCTAssertEqual(struct2.f11, 0)
        XCTAssertEqual(struct2.f12, 0xFF)
        XCTAssertEqual(struct2.f13, 0)
        XCTAssertEqual(struct2.f14, 32767)
        XCTAssertEqual(struct2.f15, 0)
        XCTAssertEqual(struct2.f16, 0xFFFF)
        XCTAssertEqual(struct2.f17, 0)
        XCTAssertEqual(struct2.f18, 2147483647)
        XCTAssertEqual(struct2.f19, 0)
        XCTAssertEqual(struct2.f20, 0xFFFFFFFF)
        XCTAssertEqual(struct2.f21, 0)
        XCTAssertEqual(struct2.f22, 9223372036854775807)
        XCTAssertEqual(struct2.f23, 0)
        XCTAssertEqual(struct2.f24, 0xFFFFFFFFFFFFFFFF)
        XCTAssertEqual(struct2.f25, 0.0)
        XCTAssertTrue(abs(struct2.f26 - 123.456) < 0.0001)
        XCTAssertEqual(struct2.f27, 0.0)
        XCTAssertTrue(abs(struct2.f28 - -123.567e+123) < 1e+123)
        XCTAssertEqual(struct2.f29, Decimal(0))
        XCTAssertEqual(struct2.f30, Decimal(string: "123456.123456") ?? .nan)
        XCTAssertEqual(struct2.f31, "")
        XCTAssertEqual(struct2.f32, "Initial string!")
        XCTAssertTrue(struct2.f33 == Date(timeIntervalSince1970: 0))
        XCTAssertTrue(struct2.f34 == Date(timeIntervalSince1970: 0))
        XCTAssertTrue(struct2.f35 > Date(timeIntervalSince1970: 1514764800)) // 01/01/2018
        XCTAssertTrue(struct2.f36 == UUID(uuidString: "00000000-0000-0000-0000-000000000000"))
        XCTAssertTrue(struct2.f37 != UUID(uuidString: "123e4567-e89b-12d3-a456-426655440000"))
        XCTAssertTrue(struct2.f38 == UUID(uuidString: "123e4567-e89b-12d3-a456-426655440000"))

        XCTAssertEqual(struct2.f100, nil)
        XCTAssertNotEqual(struct2.f101, nil)
        XCTAssertEqual(struct2.f101!, true)
        XCTAssertEqual(struct2.f102, nil)
        XCTAssertEqual(struct2.f103, nil)
        XCTAssertNotEqual(struct2.f104, nil)
        XCTAssertEqual(struct2.f104!, 0xFF)
        XCTAssertEqual(struct2.f105, nil)
        XCTAssertEqual(struct2.f106, nil)
        XCTAssertNotEqual(struct2.f107, nil)
        XCTAssertEqual(struct2.f107!, "!")
        XCTAssertEqual(struct2.f108, nil)
        XCTAssertEqual(struct2.f109, nil)
        XCTAssertNotEqual(struct2.f110, nil)
        XCTAssertEqual(struct2.f111, nil)
        XCTAssertEqual(struct2.f112, nil)
        XCTAssertNotEqual(struct2.f113, nil)
        XCTAssertEqual(struct2.f113!, 127)
        XCTAssertEqual(struct2.f114, nil)
        XCTAssertEqual(struct2.f115, nil)
        XCTAssertNotEqual(struct2.f116, nil)
        XCTAssertEqual(struct2.f116!, 0xFF)
        XCTAssertEqual(struct2.f117, nil)
        XCTAssertEqual(struct2.f118, nil)
        XCTAssertNotEqual(struct2.f119, nil)
        XCTAssertEqual(struct2.f119!, 32767)
        XCTAssertEqual(struct2.f120, nil)
        XCTAssertEqual(struct2.f121, nil)
        XCTAssertNotEqual(struct2.f122, nil)
        XCTAssertEqual(struct2.f122!, 0xFFFF)
        XCTAssertEqual(struct2.f123, nil)
        XCTAssertEqual(struct2.f124, nil)
        XCTAssertNotEqual(struct2.f125, nil)
        XCTAssertEqual(struct2.f125!, 2147483647)
        XCTAssertEqual(struct2.f126, nil)
        XCTAssertEqual(struct2.f127, nil)
        XCTAssertNotEqual(struct2.f128, nil)
        XCTAssertEqual(struct2.f128!, 0xFFFFFFFF)
        XCTAssertEqual(struct2.f129, nil)
        XCTAssertEqual(struct2.f130, nil)
        XCTAssertNotEqual(struct2.f131, nil)
        XCTAssertEqual(struct2.f131!, 9223372036854775807)
        XCTAssertEqual(struct2.f132, nil)
        XCTAssertEqual(struct2.f133, nil)
        XCTAssertNotEqual(struct2.f131, nil)
        XCTAssertEqual(struct2.f134!, 0xFFFFFFFFFFFFFFFF)
        XCTAssertEqual(struct2.f135, nil)
        XCTAssertEqual(struct2.f136, nil)
        XCTAssertNotEqual(struct2.f137, nil)
        XCTAssertTrue(abs(struct2.f137! - 123.456) < 0.0001)
        XCTAssertEqual(struct2.f138, nil)
        XCTAssertEqual(struct2.f139, nil)
        XCTAssertNotEqual(struct2.f140, nil)
        XCTAssertTrue(abs(struct2.f140! - -123.567e+123) < 1e+123)
        XCTAssertEqual(struct2.f141, nil)
        XCTAssertEqual(struct2.f142, nil)
        XCTAssertNotEqual(struct2.f143, nil)
        XCTAssertEqual(struct2.f143, Decimal(string: "123456.123456") ?? .nan)
        XCTAssertEqual(struct2.f144, nil)
        XCTAssertEqual(struct2.f145, nil)
        XCTAssertNotEqual(struct2.f146, nil)
        XCTAssertEqual(struct2.f146, "Initial string!")
        XCTAssertEqual(struct2.f147, nil)
        XCTAssertEqual(struct2.f148, nil)
        XCTAssertNotEqual(struct2.f149, nil)
        XCTAssertTrue(struct2.f149! > Date(timeIntervalSince1970: 1514764800))//GregorianCalendar(2018, 1, 1).toInstant().epochSecond)
        XCTAssertEqual(struct2.f150, nil)
        XCTAssertEqual(struct2.f151, nil)
        XCTAssertNotEqual(struct2.f152, nil)
        XCTAssertTrue(struct2.f152! == UUID(uuidString: "123e4567-e89b-12d3-a456-426655440000"))
        XCTAssertEqual(struct2.f153, nil)
        XCTAssertEqual(struct2.f154, nil)
        XCTAssertEqual(struct2.f155, nil)
        XCTAssertEqual(struct2.f156, nil)
        XCTAssertEqual(struct2.f157, nil)
        XCTAssertEqual(struct2.f158, nil)
        XCTAssertEqual(struct2.f159, nil)
        XCTAssertEqual(struct2.f160, nil)
        XCTAssertEqual(struct2.f161, nil)
        XCTAssertEqual(struct2.f162, nil)
        XCTAssertEqual(struct2.f163, nil)
        XCTAssertEqual(struct2.f164, nil)
        XCTAssertEqual(struct2.f165, nil)

        XCTAssertEqual(struct2.f1000, EnumSimple.ENUM_VALUE_0)
        XCTAssertEqual(struct2.f1001, nil)
        XCTAssertEqual(struct2.f1002, EnumTyped.ENUM_VALUE_2)
        XCTAssertEqual(struct2.f1003, nil)
        XCTAssertEqual(struct2.f1004, FlagsSimple.FLAG_VALUE_0)
        XCTAssertEqual(struct2.f1005, nil)
        XCTAssertEqual(struct2.f1006, FlagsTyped.fromSet(set: [FlagsTyped.FLAG_VALUE_2.value!, FlagsTyped.FLAG_VALUE_4.value!, FlagsTyped.FLAG_VALUE_6.value!]))
        XCTAssertEqual(struct2.f1007, nil)
        XCTAssertEqual(struct2.f1009, nil)
        XCTAssertEqual(struct2.f1011, nil)

        XCTAssertEqual(struct2.f1, struct1.f1)
        XCTAssertEqual(struct2.f2, struct1.f2)
        XCTAssertEqual(struct2.f3, struct1.f3)
        XCTAssertEqual(struct2.f4, struct1.f4)
        XCTAssertEqual(struct2.f5, struct1.f5)
        XCTAssertEqual(struct2.f6, struct1.f6)
        XCTAssertEqual(struct2.f7, struct1.f7)
        XCTAssertEqual(struct2.f8, struct1.f8)
        XCTAssertEqual(struct2.f9, struct1.f9)
        XCTAssertEqual(struct2.f10, struct1.f10)
        XCTAssertEqual(struct2.f11, struct1.f11)
        XCTAssertEqual(struct2.f12, struct1.f12)
        XCTAssertEqual(struct2.f13, struct1.f13)
        XCTAssertEqual(struct2.f14, struct1.f14)
        XCTAssertEqual(struct2.f15, struct1.f15)
        XCTAssertEqual(struct2.f16, struct1.f16)
        XCTAssertEqual(struct2.f17, struct1.f17)
        XCTAssertEqual(struct2.f18, struct1.f18)
        XCTAssertEqual(struct2.f19, struct1.f19)
        XCTAssertEqual(struct2.f20, struct1.f20)
        XCTAssertEqual(struct2.f21, struct1.f21)
        XCTAssertEqual(struct2.f22, struct1.f22)
        XCTAssertEqual(struct2.f23, struct1.f23)
        XCTAssertEqual(struct2.f24, struct1.f24)
        XCTAssertEqual(struct2.f25, struct1.f25)
        XCTAssertEqual(struct2.f26, struct1.f26)
        XCTAssertEqual(struct2.f27, struct1.f27)
        XCTAssertEqual(struct2.f28, struct1.f28)
        XCTAssertEqual(struct2.f29, struct1.f29)
        XCTAssertEqual(struct2.f30, struct1.f30)
        XCTAssertEqual(struct2.f31, struct1.f31)
        XCTAssertEqual(struct2.f32, struct1.f32)
        XCTAssertEqual(struct2.f33, struct1.f33)
        XCTAssertEqual(struct2.f34, struct1.f34)
        XCTAssertEqual(floor(struct2.f35.timeIntervalSince1970 * 1000), floor(struct1.f35.timeIntervalSince1970 * 1000))
        XCTAssertEqual(struct2.f36, struct1.f36)
        XCTAssertEqual(struct2.f37, struct1.f37)
        XCTAssertEqual(struct2.f38, struct1.f38)
        XCTAssertEqual(struct2.f39, struct1.f39)
        XCTAssertEqual(struct2.f40, struct1.f40)

        XCTAssertEqual(struct2.f100, struct1.f100)
        XCTAssertEqual(struct2.f101, struct1.f101)
        XCTAssertEqual(struct2.f102, struct1.f102)
        XCTAssertEqual(struct2.f103, struct1.f103)
        XCTAssertEqual(struct2.f104, struct1.f104)
        XCTAssertEqual(struct2.f105, struct1.f105)
        XCTAssertEqual(struct2.f106, struct1.f106)
        XCTAssertEqual(struct2.f107, struct1.f107)
        XCTAssertEqual(struct2.f108, struct1.f108)
        XCTAssertEqual(struct2.f109, struct1.f109)
        XCTAssertEqual(struct2.f110, struct1.f110)
        XCTAssertEqual(struct2.f111, struct1.f111)
        XCTAssertEqual(struct2.f112, struct1.f112)
        XCTAssertEqual(struct2.f113, struct1.f113)
        XCTAssertEqual(struct2.f114, struct1.f114)
        XCTAssertEqual(struct2.f115, struct1.f115)
        XCTAssertEqual(struct2.f116, struct1.f116)
        XCTAssertEqual(struct2.f117, struct1.f117)
        XCTAssertEqual(struct2.f118, struct1.f118)
        XCTAssertEqual(struct2.f119, struct1.f119)
        XCTAssertEqual(struct2.f120, struct1.f120)
        XCTAssertEqual(struct2.f121, struct1.f121)
        XCTAssertEqual(struct2.f122, struct1.f122)
        XCTAssertEqual(struct2.f123, struct1.f123)
        XCTAssertEqual(struct2.f124, struct1.f124)
        XCTAssertEqual(struct2.f125, struct1.f125)
        XCTAssertEqual(struct2.f126, struct1.f126)
        XCTAssertEqual(struct2.f127, struct1.f127)
        XCTAssertEqual(struct2.f128, struct1.f128)
        XCTAssertEqual(struct2.f129, struct1.f129)
        XCTAssertEqual(struct2.f130, struct1.f130)
        XCTAssertEqual(struct2.f131, struct1.f131)
        XCTAssertEqual(struct2.f132, struct1.f132)
        XCTAssertEqual(struct2.f133, struct1.f133)
        XCTAssertEqual(struct2.f134, struct1.f134)
        XCTAssertEqual(struct2.f135, struct1.f135)
        XCTAssertEqual(struct2.f136, struct1.f136)
        XCTAssertEqual(struct2.f137, struct1.f137)
        XCTAssertEqual(struct2.f138, struct1.f138)
        XCTAssertEqual(struct2.f139, struct1.f139)
        XCTAssertEqual(struct2.f140, struct1.f140)
        XCTAssertEqual(struct2.f141, struct1.f141)
        XCTAssertEqual(struct2.f142, struct1.f142)
        XCTAssertEqual(struct2.f143, struct1.f143)
        XCTAssertEqual(struct2.f144, struct1.f144)
        XCTAssertEqual(struct2.f145, struct1.f145)
        XCTAssertEqual(struct2.f146, struct1.f146)
        XCTAssertEqual(struct2.f147, struct1.f147)
        XCTAssertEqual(struct2.f148, struct1.f148)
        XCTAssertEqual(floor(struct2.f149!.timeIntervalSince1970 * 1000), floor(struct1.f149!.timeIntervalSince1970 * 1000))
        XCTAssertEqual(struct2.f150, struct1.f150)
        XCTAssertEqual(struct2.f151, struct1.f151)
        XCTAssertEqual(struct2.f152, struct1.f152)
        XCTAssertEqual(struct2.f153, struct1.f153)
        XCTAssertEqual(struct2.f154, struct1.f154)
        XCTAssertEqual(struct2.f155, struct1.f155)
        XCTAssertEqual(struct2.f156, struct1.f156)
        XCTAssertEqual(struct2.f157, struct1.f157)

        XCTAssertEqual(struct2.f1000, struct1.f1000)
        XCTAssertEqual(struct2.f1001, struct1.f1001)
        XCTAssertEqual(struct2.f1002, struct1.f1002)
        XCTAssertEqual(struct2.f1003, struct1.f1003)
        XCTAssertEqual(struct2.f1004, struct1.f1004)
        XCTAssertEqual(struct2.f1005, struct1.f1005)
        XCTAssertEqual(struct2.f1006, struct1.f1006)
        XCTAssertEqual(struct2.f1007, struct1.f1007)
    }

    func testSerializationStructBytes() {
        // Create a new struct
        var struct1 = StructBytes()
        struct1.f1 = "ABC".data(using: .utf8)!
        struct1.f2 = "test".data(using: .utf8)

        // Serialize the struct to the FBE stream
        let writer = StructBytesFinalModel()
        XCTAssertEqual(writer.fbeType, 120)

        let serialized = try! writer.serialize(value: struct1)
        XCTAssertEqual(serialized, writer.buffer.size)
        XCTAssertTrue(writer.verify())
        writer.next(prev: serialized)

        // Check the serialized FBE size
        XCTAssertEqual(writer.buffer.size, 25)

        // Deserialize the struct from the FBE stream
        var struct2 = StructBytes()
        let reader = StructBytesFinalModel()
        XCTAssertEqual(reader.fbeType, 120)

        reader.attach(buffer: writer.buffer)
        XCTAssertTrue(reader.verify())
        let deserialized = reader.deserialize(value: &struct2)
        XCTAssertEqual(deserialized, reader.buffer.size)
        reader.next(prev: deserialized)

        XCTAssertEqual(struct2.f1.count, 3)
        XCTAssertEqual(Character(UnicodeScalar(Array(struct2.f1)[0])), "A")
        XCTAssertEqual(Character(UnicodeScalar(Array(struct2.f1)[1])), "B")
        XCTAssertEqual(Character(UnicodeScalar(Array(struct2.f1)[2])), "C")
        XCTAssertNotEqual(struct2.f2, nil)
        XCTAssertEqual(struct2.f2!.count, 4)
        XCTAssertEqual(Character(UnicodeScalar(Array(struct2.f2!)[0])), "t")
        XCTAssertEqual(Character(UnicodeScalar(Array(struct2.f2!)[1])), "e")
        XCTAssertEqual(Character(UnicodeScalar(Array(struct2.f2!)[2])), "s")
        XCTAssertEqual(Character(UnicodeScalar(Array(struct2.f2!)[3])), "t")
        XCTAssertEqual(struct2.f3, nil)
    }

    func testSerializationStructArray() {
        // Create a new struct
        var struct1 = StructArray()
        struct1.f1 = Array(repeating: 0, count: 2)
        struct1.f1[0] = 48
        struct1.f1[1] = 65
        struct1.f2 = Array(repeating: nil, count: 2)
        struct1.f2[0] = 97
        struct1.f2[1] = nil
        struct1.f3 = Array(repeating: "000".data(using: .utf8)!, count: 2)
        struct1.f3[0] = "000".data(using: .utf8)!
        struct1.f3[1] = "AAA".data(using: .utf8)!
        struct1.f4 = Array(repeating: nil, count: 2)
        struct1.f4[0] = "aaa".data(using: .utf8)!
        struct1.f4[1] = nil
        struct1.f5 = Array(repeating: EnumSimple.ENUM_VALUE_1, count: 2)
        struct1.f5[0] = EnumSimple.ENUM_VALUE_1
        struct1.f5[1] = EnumSimple.ENUM_VALUE_2
        struct1.f6 = Array(repeating: nil, count: 2)
        struct1.f6[0] = EnumSimple.ENUM_VALUE_1
        struct1.f6[1] = nil
        struct1.f7 = Array(repeating: FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]), count: 2)
        struct1.f7[0] = FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!])
        struct1.f7[1] = FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!, FlagsSimple.FLAG_VALUE_3.value!])
        struct1.f8 = Array(repeating: nil, count: 2)
        struct1.f8[0] = FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!])
        struct1.f8[1] = nil
        struct1.f9 = Array(repeating: StructSimple(), count: 2)
        struct1.f9[0] = StructSimple()
        struct1.f9[1] = StructSimple()
        struct1.f10 = Array(repeating: nil, count: 2)
        struct1.f10[0] = StructSimple()
        struct1.f10[1] = nil

        // Serialize the struct to the FBE stream
        let writer = StructArrayFinalModel()
        XCTAssertEqual(writer.fbeType, 125)

        let serialized = try! writer.serialize(value: struct1)
        XCTAssertEqual(serialized, writer.buffer.size)
        XCTAssertTrue(writer.verify())
        writer.next(prev: serialized)

        // Check the serialized FBE size
        XCTAssertEqual(writer.buffer.size, 954)

        // Deserialize the struct from the FBE stream
        var struct2 = StructArray()
        let reader = StructArrayFinalModel()
        XCTAssertEqual(reader.fbeType, 125)

        reader.attach(buffer: writer.buffer)
        XCTAssertTrue(reader.verify())
        let deserialized = reader.deserialize(value: &struct2)
        XCTAssertEqual(deserialized, reader.buffer.size)
        reader.next(prev: deserialized)

        XCTAssertEqual(struct2.f1.count, 2)
        XCTAssertEqual(struct2.f1[0], 48)
        XCTAssertEqual(struct2.f1[1], 65)
        XCTAssertEqual(struct2.f2.count, 2)
        XCTAssertEqual(struct2.f2[0], 97)
        XCTAssertEqual(struct2.f2[1], nil)
        XCTAssertEqual(struct2.f3.count, 2)
        XCTAssertEqual(struct2.f3[0].count, 3)
        XCTAssertEqual(struct2.f3[0][0], 48)
        XCTAssertEqual(struct2.f3[0][1], 48)
        XCTAssertEqual(struct2.f3[0][2], 48)
        XCTAssertEqual(struct2.f3[1].count, 3)
        XCTAssertEqual(struct2.f3[1][0], 65)
        XCTAssertEqual(struct2.f3[1][1], 65)
        XCTAssertEqual(struct2.f3[1][2], 65)
        XCTAssertEqual(struct2.f4.count, 2)
        XCTAssertNotEqual(struct2.f4[0], nil)
        XCTAssertEqual(struct2.f4[0]!.count, 3)
        XCTAssertEqual(struct2.f4[0]![0], 97)
        XCTAssertEqual(struct2.f4[0]![1], 97)
        XCTAssertEqual(struct2.f4[0]![2], 97)
        XCTAssertEqual(struct2.f4[1], nil)
        XCTAssertEqual(struct2.f5.count, 2)
        XCTAssertEqual(struct2.f5[0], EnumSimple.ENUM_VALUE_1)
        XCTAssertEqual(struct2.f5[1], EnumSimple.ENUM_VALUE_2)
        XCTAssertEqual(struct2.f6.count, 2)
        XCTAssertEqual(struct2.f6[0], EnumSimple.ENUM_VALUE_1)
        XCTAssertEqual(struct2.f6[1], nil)
        XCTAssertEqual(struct2.f7.count, 2)
        XCTAssertEqual(struct2.f7[0], FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        XCTAssertEqual(struct2.f7[1], FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!, FlagsSimple.FLAG_VALUE_3.value!]))
        XCTAssertEqual(struct2.f8.count, 2)
        XCTAssertEqual(struct2.f8[0], FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        XCTAssertEqual(struct2.f8[1], nil)
        XCTAssertEqual(struct2.f9.count, 2)
        XCTAssertEqual(struct2.f9[0].f2, true)
        XCTAssertEqual(struct2.f9[0].f12, 0xFF)
        XCTAssertEqual(struct2.f9[0].f32, "Initial string!")
        XCTAssertEqual(struct2.f9[1].f2, true)
        XCTAssertEqual(struct2.f9[1].f12, 0xFF)
        XCTAssertEqual(struct2.f9[1].f32, "Initial string!")
        XCTAssertEqual(struct2.f10.count, 2)
        XCTAssertNotEqual(struct2.f10[0], nil)
        XCTAssertEqual(struct2.f10[0]!.f2, true)
        XCTAssertEqual(struct2.f10[0]!.f12, 0xFF)
        XCTAssertEqual(struct2.f10[0]!.f32, "Initial string!")
        XCTAssertEqual(struct2.f10[1], nil)
    }

    func testSerializationStructVector() {
        // Create a new struct
        var struct1 = StructVector()
        struct1.f1.append(48)
        struct1.f1.append(65)
        struct1.f2.append(97)
        struct1.f2.append(nil)
        struct1.f3.append("000".data(using: .utf8)!)
        struct1.f3.append("AAA".data(using: .utf8)!)
        struct1.f4.append("aaa".data(using: .utf8)!)
        struct1.f4.append(nil)
        struct1.f5.append(EnumSimple.ENUM_VALUE_1)
        struct1.f5.append(EnumSimple.ENUM_VALUE_2)
        struct1.f6.append(EnumSimple.ENUM_VALUE_1)
        struct1.f6.append(nil)
        struct1.f7.append(FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        struct1.f7.append(FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!, FlagsSimple.FLAG_VALUE_3.value!]))
        struct1.f8.append(FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        struct1.f8.append(nil)
        struct1.f9.append(StructSimple())
        struct1.f9.append(StructSimple())
        struct1.f10.append(StructSimple())
        struct1.f10.append(nil)

        // Serialize the struct to the FBE stream
        let writer = StructVectorFinalModel()
        XCTAssertEqual(writer.fbeType, 130)

        let serialized = try! writer.serialize(value: struct1)
        XCTAssertEqual(serialized, writer.buffer.size)
        XCTAssertTrue(writer.verify())
        writer.next(prev: serialized)

        // Check the serialized FBE size
        XCTAssertEqual(writer.buffer.size, 994)

        // Deserialize the struct from the FBE stream
        var struct2 = StructVector()
        let reader = StructVectorFinalModel()
        XCTAssertEqual(reader.fbeType, 130)

        reader.attach(buffer: writer.buffer)
        XCTAssertTrue(reader.verify())
        let deserialized = reader.deserialize(value: &struct2)
        XCTAssertEqual(deserialized, reader.buffer.size)
        reader.next(prev: deserialized)

        XCTAssertEqual(struct2.f1.count, 2)
        XCTAssertEqual(struct2.f1[0], 48)
        XCTAssertEqual(struct2.f1[1], 65)
        XCTAssertEqual(struct2.f2.count, 2)
        XCTAssertEqual(struct2.f2[0], 97)
        XCTAssertEqual(struct2.f2[1], nil)
        XCTAssertEqual(struct2.f3.count, 2)
        XCTAssertEqual(struct2.f3[0].count, 3)
        XCTAssertEqual(struct2.f3[0][0], 48)
        XCTAssertEqual(struct2.f3[0][1], 48)
        XCTAssertEqual(struct2.f3[0][2], 48)
        XCTAssertEqual(struct2.f3[1].count, 3)
        XCTAssertEqual(struct2.f3[1][0], 65)
        XCTAssertEqual(struct2.f3[1][1], 65)
        XCTAssertEqual(struct2.f3[1][2], 65)
        XCTAssertEqual(struct2.f4.count, 2)
        XCTAssertNotEqual(struct2.f4[0], nil)
        XCTAssertEqual(struct2.f4[0]!.count, 3)
        XCTAssertEqual(struct2.f4[0]![0], 97)
        XCTAssertEqual(struct2.f4[0]![1], 97)
        XCTAssertEqual(struct2.f4[0]![2], 97)
        XCTAssertEqual(struct2.f4[1], nil)
        XCTAssertEqual(struct2.f5.count, 2)
        XCTAssertEqual(struct2.f5[0], EnumSimple.ENUM_VALUE_1)
        XCTAssertEqual(struct2.f5[1], EnumSimple.ENUM_VALUE_2)
        XCTAssertEqual(struct2.f6.count, 2)
        XCTAssertEqual(struct2.f6[0], EnumSimple.ENUM_VALUE_1)
        XCTAssertEqual(struct2.f6[1], nil)
        XCTAssertEqual(struct2.f7.count, 2)
        XCTAssertEqual(struct2.f7[0], FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        XCTAssertEqual(struct2.f7[1], FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!, FlagsSimple.FLAG_VALUE_3.value!]))
        XCTAssertEqual(struct2.f8.count, 2)
        XCTAssertEqual(struct2.f8[0], FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        XCTAssertEqual(struct2.f8[1], nil)
        XCTAssertEqual(struct2.f9.count, 2)
        XCTAssertEqual(struct2.f9[0].f2, true)
        XCTAssertEqual(struct2.f9[0].f12, 0xFF)
        XCTAssertEqual(struct2.f9[0].f32, "Initial string!")
        XCTAssertEqual(struct2.f9[1].f2, true)
        XCTAssertEqual(struct2.f9[1].f12, 0xFF)
        XCTAssertEqual(struct2.f9[1].f32, "Initial string!")
        XCTAssertEqual(struct2.f10.count, 2)
        XCTAssertNotEqual(struct2.f10[0], nil)
        XCTAssertEqual(struct2.f10[0]!.f2, true)
        XCTAssertEqual(struct2.f10[0]!.f12, 0xFF)
        XCTAssertEqual(struct2.f10[0]!.f32, "Initial string!")
        XCTAssertEqual(struct2.f10[1], nil)
    }

    func testSerializationStructList() {
        // Create a new struct
        var struct1 = StructList()
        struct1.f1.append(48)
        struct1.f1.append(65)
        struct1.f2.append(97)
        struct1.f2.append(nil)
        struct1.f3.append("000".data(using: .utf8)!)
        struct1.f3.append("AAA".data(using: .utf8)!)
        struct1.f4.append("aaa".data(using: .utf8)!)
        struct1.f4.append(nil)
        struct1.f5.append(EnumSimple.ENUM_VALUE_1)
        struct1.f5.append(EnumSimple.ENUM_VALUE_2)
        struct1.f6.append(EnumSimple.ENUM_VALUE_1)
        struct1.f6.append(nil)
        struct1.f7.append(FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        struct1.f7.append(FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!, FlagsSimple.FLAG_VALUE_3.value!]))
        struct1.f8.append(FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        struct1.f8.append(nil)
        struct1.f9.append(StructSimple())
        struct1.f9.append(StructSimple())
        struct1.f10.append(StructSimple())
        struct1.f10.append(nil)

        // Serialize the struct to the FBE stream
        let writer = StructListFinalModel()
        XCTAssertEqual(writer.fbeType, 131)

        let serialized = try! writer.serialize(value: struct1)
        XCTAssertEqual(serialized, writer.buffer.size)
        XCTAssertTrue(writer.verify())
        writer.next(prev: serialized)

        // Check the serialized FBE size
        XCTAssertEqual(writer.buffer.size, 994)

        // Deserialize the struct from the FBE stream
        var struct2 = StructList()
        let reader = StructListFinalModel()
        XCTAssertEqual(reader.fbeType, 131)

        reader.attach(buffer: writer.buffer)
        XCTAssertTrue(reader.verify())
        let deserialized = reader.deserialize(value: &struct2)
        XCTAssertEqual(deserialized, reader.buffer.size)
        reader.next(prev: deserialized)

        XCTAssertEqual(struct2.f1.count, 2)
        XCTAssertEqual(struct2.f1.first, 48)
        XCTAssertEqual(struct2.f1.last, 65)
        XCTAssertEqual(struct2.f2.count, 2)
        XCTAssertEqual(struct2.f2.first!, 97)
        XCTAssertEqual(struct2.f2.last!, nil)
        XCTAssertEqual(struct2.f3.count, 2)
        XCTAssertEqual(struct2.f3.first!.count, 3)
        XCTAssertEqual(struct2.f3.first![0], 48)
        XCTAssertEqual(struct2.f3.first![1], 48)
        XCTAssertEqual(struct2.f3.first![2], 48)
        XCTAssertEqual(struct2.f3.last!.count, 3)
        XCTAssertEqual(struct2.f3.last![0], 65)
        XCTAssertEqual(struct2.f3.last![1], 65)
        XCTAssertEqual(struct2.f3.last![2], 65)
        XCTAssertEqual(struct2.f4.count, 2)
        XCTAssertNotEqual(struct2.f4.first, nil)
        XCTAssertEqual(struct2.f4.first!!.count, 3)
        XCTAssertEqual(struct2.f4.first!![0], 97)
        XCTAssertEqual(struct2.f4.first!![1], 97)
        XCTAssertEqual(struct2.f4.first!![2], 97)
        XCTAssertEqual(struct2.f4.last!, nil)
        XCTAssertEqual(struct2.f5.count, 2)
        XCTAssertEqual(struct2.f5.first, EnumSimple.ENUM_VALUE_1)
        XCTAssertEqual(struct2.f5.last, EnumSimple.ENUM_VALUE_2)
        XCTAssertEqual(struct2.f6.count, 2)
        XCTAssertEqual(struct2.f6.first, EnumSimple.ENUM_VALUE_1)
        XCTAssertEqual(struct2.f6.last!, nil)
        XCTAssertEqual(struct2.f7.count, 2)
        XCTAssertEqual(struct2.f7.first, FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        XCTAssertEqual(struct2.f7.last, FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!, FlagsSimple.FLAG_VALUE_3.value!]))
        XCTAssertEqual(struct2.f8.count, 2)
        XCTAssertEqual(struct2.f8.first, FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        XCTAssertEqual(struct2.f8.last!, nil)
        XCTAssertEqual(struct2.f9.count, 2)
        XCTAssertEqual(struct2.f9.first!.f2, true)
        XCTAssertEqual(struct2.f9.first!.f12, 0xFF)
        XCTAssertEqual(struct2.f9.first!.f32, "Initial string!")
        XCTAssertEqual(struct2.f9.last!.f2, true)
        XCTAssertEqual(struct2.f9.last!.f12, 0xFF)
        XCTAssertEqual(struct2.f9.last!.f32, "Initial string!")
        XCTAssertEqual(struct2.f10.count, 2)
        XCTAssertNotEqual(struct2.f10.first, nil)
        XCTAssertEqual(struct2.f10.first!!.f2, true)
        XCTAssertEqual(struct2.f10.first!!.f12, 0xFF)
        XCTAssertEqual(struct2.f10.first!!.f32, "Initial string!")
        XCTAssertEqual(struct2.f10.last!, nil)
    }

    func testSerializationStructSet() {
        // Create a new struct
        var struct1 = StructSet()
        struct1.f1.append(48)
        struct1.f1.append(65)
        struct1.f1.append(97)
        struct1.f2.append(EnumSimple.ENUM_VALUE_1)
        struct1.f2.append(EnumSimple.ENUM_VALUE_2)
        struct1.f3.append(FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        struct1.f3.append(FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!, FlagsSimple.FLAG_VALUE_3.value!]))
        var s1 = StructSimple()
        s1.id = 48
        struct1.f4.append(s1)
        var s2 = StructSimple()
        s2.id = 65
        struct1.f4.append(s2)

        // Serialize the struct to the FBE stream
        let writer = StructSetFinalModel()
        XCTAssertEqual(writer.fbeType, 132)

        let serialized = try! writer.serialize(value: struct1)
        XCTAssertEqual(serialized, writer.buffer.size)
        XCTAssertTrue(writer.verify())
        writer.next(prev: serialized)

        // Check the serialized FBE size
        XCTAssertEqual(writer.buffer.size, 635)

        // Deserialize the struct from the FBE stream
        var struct2 = StructSet()
        let reader = StructSetFinalModel()
        XCTAssertEqual(reader.fbeType, 132)

        reader.attach(buffer: writer.buffer)
        XCTAssertTrue(reader.verify())
        let deserialized = reader.deserialize(value: &struct2)
        XCTAssertEqual(deserialized, reader.buffer.size)
        reader.next(prev: deserialized)

        XCTAssertEqual(struct2.f1.count, 3)
        XCTAssertTrue(struct2.f1.contains(48))
        XCTAssertTrue(struct2.f1.contains(65))
        XCTAssertTrue(struct2.f1.contains(97))
        XCTAssertEqual(struct2.f2.count, 2)
        XCTAssertTrue(struct2.f2.contains(EnumSimple.ENUM_VALUE_1))
        XCTAssertTrue(struct2.f2.contains(EnumSimple.ENUM_VALUE_2))
        XCTAssertEqual(struct2.f3.count, 2)
        XCTAssertTrue(struct2.f3.contains(FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!])))
        XCTAssertTrue(struct2.f3.contains(FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!, FlagsSimple.FLAG_VALUE_3.value!])))
        XCTAssertEqual(struct2.f4.count, 2)
        XCTAssertTrue(struct2.f4.contains(s1))
        XCTAssertTrue(struct2.f4.contains(s2))
    }

    func testSerializationStructMap() {
        // Create a new struct
        var struct1 = StructMap()
        struct1.f1[10] = 48
        struct1.f1[20] = 65
        struct1.f2[10] = 97
        struct1.f2.updateValue(nil, forKey: 20)
        struct1.f3[10] = "000".data(using: .utf8)!
        struct1.f3[20] = "AAA".data(using: .utf8)!
        struct1.f4[10] = "aaa".data(using: .utf8)!
        struct1.f4.updateValue(nil, forKey: 20)
        struct1.f5[10] = EnumSimple.ENUM_VALUE_1
        struct1.f5[20] = EnumSimple.ENUM_VALUE_2
        struct1.f6[10] = EnumSimple.ENUM_VALUE_1
        struct1.f6.updateValue(nil, forKey: 20)
        struct1.f7[10] = FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!])
        struct1.f7[20] = FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!, FlagsSimple.FLAG_VALUE_3.value!])
        struct1.f8[10] = FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!])
        struct1.f8.updateValue(nil, forKey: 20)
        var s1 = StructSimple()
        s1.id = 48
        struct1.f9[10] = s1
        var s2 = StructSimple()
        s2.id = 65
        struct1.f9[20] = s2
        struct1.f10[10] = s1
        struct1.f10.updateValue(nil, forKey: 20)

        // Serialize the struct to the FBE stream
        let writer = StructMapFinalModel()
        XCTAssertEqual(writer.fbeType, 140)

        let serialized = try! writer.serialize(value: struct1)
        XCTAssertEqual(serialized, writer.buffer.size)
        XCTAssertTrue(writer.verify())
        writer.next(prev: serialized)

        // Check the serialized FBE size
        XCTAssertEqual(writer.buffer.size, 1074)

        // Deserialize the struct from the FBE stream
        var struct2 = StructMap()
        let reader = StructMapFinalModel()
        XCTAssertEqual(reader.fbeType, 140)

        reader.attach(buffer: writer.buffer)
        XCTAssertTrue(reader.verify())
        let deserialized = reader.deserialize(value: &struct2)
        XCTAssertEqual(deserialized, reader.buffer.size)
        reader.next(prev: deserialized)

        XCTAssertEqual(struct2.f1.count, 2)
        XCTAssertEqual(struct2.f1[10]!, 48)
        XCTAssertEqual(struct2.f1[20]!, 65)
        XCTAssertEqual(struct2.f2.count, 2)
        XCTAssertEqual(struct2.f2[10]!, 97)
        XCTAssertEqual(struct2.f2[20]!, nil)
        XCTAssertEqual(struct2.f3.count, 2)
        XCTAssertEqual(struct2.f3[10]!.count, 3)
        XCTAssertEqual(struct2.f3[20]!.count, 3)
        XCTAssertEqual(struct2.f4.count, 2)
        XCTAssertEqual(struct2.f4[10]!!.count, 3)
        XCTAssertEqual(struct2.f4[20]!, nil)
        XCTAssertEqual(struct2.f5.count, 2)
        XCTAssertEqual(struct2.f5[10], EnumSimple.ENUM_VALUE_1)
        XCTAssertEqual(struct2.f5[20], EnumSimple.ENUM_VALUE_2)
        XCTAssertEqual(struct2.f6.count, 2)
        XCTAssertEqual(struct2.f6[10], EnumSimple.ENUM_VALUE_1)
        XCTAssertEqual(struct2.f6[20]!, nil)
        XCTAssertEqual(struct2.f7.count, 2)
        XCTAssertEqual(struct2.f7[10], FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        XCTAssertEqual(struct2.f7[20], FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!, FlagsSimple.FLAG_VALUE_3.value!]))
        XCTAssertEqual(struct2.f8.count, 2)
        XCTAssertEqual(struct2.f8[10], FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        XCTAssertEqual(struct2.f8[20]!, nil)
        XCTAssertEqual(struct2.f9.count, 2)
        XCTAssertEqual(struct2.f9[10]!.id, 48)
        XCTAssertEqual(struct2.f9[20]!.id, 65)
        XCTAssertEqual(struct2.f10.count, 2)
        XCTAssertEqual(struct2.f10[10]!!.id, 48)
        XCTAssertEqual(struct2.f10[20]!, nil)
    }

    func testSerializationStructHash() {
        // Create a new struct
        var struct1 = StructHash()
        struct1.f1["10"] = 48
        struct1.f1["20"] = 65
        struct1.f2["10"] = 97
        struct1.f2.updateValue(nil, forKey: "20")
        struct1.f3["10"] = "000".data(using: .utf8)!
        struct1.f3["20"] = "AAA".data(using: .utf8)!
        struct1.f4["10"] = "aaa".data(using: .utf8)!
        struct1.f4.updateValue(nil, forKey: "20")
        struct1.f5["10"] = EnumSimple.ENUM_VALUE_1
        struct1.f5["20"] = EnumSimple.ENUM_VALUE_2
        struct1.f6["10"] = EnumSimple.ENUM_VALUE_1
        struct1.f6.updateValue(nil, forKey: "20")
        struct1.f7["10"] = FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!])
        struct1.f7["20"] = FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!, FlagsSimple.FLAG_VALUE_3.value!])
        struct1.f8["10"] = FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!])
        struct1.f8.updateValue(nil, forKey: "20")
        var s1 = StructSimple()
        s1.id = 48
        struct1.f9["10"] = s1
        var s2 = StructSimple()
        s2.id = 65
        struct1.f9["20"] = s2
        struct1.f10["10"] = s1
        struct1.f10.updateValue(nil, forKey: "20")

        // Serialize the struct to the FBE stream
        let writer = StructHashFinalModel()
        XCTAssertEqual(writer.fbeType, 141)

        let serialized = try! writer.serialize(value: struct1)
        XCTAssertEqual(serialized, writer.buffer.size)
        XCTAssertTrue(writer.verify())
        writer.next(prev: serialized)

        // Check the serialized FBE size
        XCTAssertEqual(writer.buffer.size, 1114)

        // Deserialize the struct from the FBE stream
        var struct2 = StructHash()
        let reader = StructHashFinalModel()
        XCTAssertEqual(reader.fbeType, 141)

        reader.attach(buffer: writer.buffer)
        XCTAssertTrue(reader.verify())
        let deserialized = reader.deserialize(value: &struct2)
        XCTAssertEqual(deserialized, reader.buffer.size)
        reader.next(prev: deserialized)

        XCTAssertEqual(struct2.f1.count, 2)
        XCTAssertEqual(struct2.f1["10"]!, 48)
        XCTAssertEqual(struct2.f1["20"]!, 65)
        XCTAssertEqual(struct2.f2.count, 2)
        XCTAssertEqual(struct2.f2["10"]!, 97)
        XCTAssertEqual(struct2.f2["20"]!, nil)
        XCTAssertEqual(struct2.f3.count, 2)
        XCTAssertEqual(struct2.f3["10"]!.count, 3)
        XCTAssertEqual(struct2.f3["20"]!.count, 3)
        XCTAssertEqual(struct2.f4.count, 2)
        XCTAssertEqual(struct2.f4["10"]!!.count, 3)
        XCTAssertEqual(struct2.f4["20"]!, nil)
        XCTAssertEqual(struct2.f5.count, 2)
        XCTAssertEqual(struct2.f5["10"], EnumSimple.ENUM_VALUE_1)
        XCTAssertEqual(struct2.f5["20"], EnumSimple.ENUM_VALUE_2)
        XCTAssertEqual(struct2.f6.count, 2)
        XCTAssertEqual(struct2.f6["10"], EnumSimple.ENUM_VALUE_1)
        XCTAssertEqual(struct2.f6["20"]!, nil)
        XCTAssertEqual(struct2.f7.count, 2)
        XCTAssertEqual(struct2.f7["10"], FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        XCTAssertEqual(struct2.f7["20"], FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!, FlagsSimple.FLAG_VALUE_3.value!]))
        XCTAssertEqual(struct2.f8.count, 2)
        XCTAssertEqual(struct2.f8["10"], FlagsSimple.fromSet(set: [FlagsSimple.FLAG_VALUE_1.value!, FlagsSimple.FLAG_VALUE_2.value!]))
        XCTAssertEqual(struct2.f8["20"]!, nil)
        XCTAssertEqual(struct2.f9.count, 2)
        XCTAssertEqual(struct2.f9["10"]!.id, 48)
        XCTAssertEqual(struct2.f9["20"]!.id, 65)
        XCTAssertEqual(struct2.f10.count, 2)
        XCTAssertEqual(struct2.f10["10"]!!.id, 48)
        XCTAssertEqual(struct2.f10["20"]!, nil)
    }

    func testSerializationStructHashExtended() {
        // Create a new struct
        var struct1 = StructHashEx()
        var s1 = StructSimple()
        s1.id = 48
        struct1.f1[s1] = StructNested()
        var s2 = StructSimple()
        s2.id = 65
        struct1.f1[s2] = StructNested()
        struct1.f2[s1] = StructNested()
        struct1.f2.updateValue(nil, forKey: s2)

        // Serialize the struct to the FBE stream
        let writer = StructHashExFinalModel()
        XCTAssertEqual(writer.fbeType, 142)

        let serialized = try! writer.serialize(value: struct1)
        XCTAssertEqual(serialized, writer.buffer.size)
        XCTAssertTrue(writer.verify())
        writer.next(prev: serialized)

        // Check the serialized FBE size
        XCTAssertEqual(writer.buffer.size, 4979)

        // Deserialize the struct from the FBE stream
        var struct2 = StructHashEx()
        let reader = StructHashExFinalModel()
        XCTAssertEqual(reader.fbeType, 142)

        reader.attach(buffer: writer.buffer)
        XCTAssertTrue(reader.verify())
        let deserialized = reader.deserialize(value: &struct2)
        XCTAssertEqual(deserialized, reader.buffer.size)
        reader.next(prev: deserialized)

        XCTAssertEqual(struct2.f1.count, 2)
        XCTAssertEqual(struct2.f1[s1]!.f1002, EnumTyped.ENUM_VALUE_2)
        XCTAssertEqual(struct2.f1[s2]!.f1002, EnumTyped.ENUM_VALUE_2)
        XCTAssertEqual(struct2.f2.count, 2)
        XCTAssertEqual(struct2.f2[s1]!!.f1002, EnumTyped.ENUM_VALUE_2)
        XCTAssertEqual(struct2.f2[s2]!, nil)
    }
}
